pub mod db;
pub mod download;
pub mod protocol;
pub mod setting;
mod utils;
pub mod webserver;
pub mod websocket;
pub mod window;
mod tray;

use crate::utils::set_app;
use std::thread;
use tauri::App;
use tokio::runtime::Runtime;

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
    let migrations = db::get_migrations().expect("sql初始化失败");
    tauri::Builder::default()
        .setup(setup)
        .plugin(tauri_plugin_os::init())
        .plugin(tauri_plugin_opener::init())
        .plugin(tauri_plugin_websocket::init())
        .plugin(tauri_plugin_sql::Builder::default().build())
        .plugin(
            tauri_plugin_sql::Builder::default()
                .add_migrations("sqlite:download_manager.db", migrations)
                .build(),
        )
        .invoke_handler(tauri::generate_handler![
            download::download,
            utils::open_file,
            utils::open_folder
        ])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

fn setup(app: &mut App) -> Result<(), Box<dyn std::error::Error>> {
    // 初始化APP，存储应用句柄
    set_app(app.handle().clone()).expect("Set app Failed");

    // 初始化托盘
    if let Err(e) = tray::tray_setup() {
        eprintln!("error while tray: {:?}", e);
    };

    // 初始化db
    if let Err(e) = db::db_setup() {
        eprintln!("error while db setting up setup: {:?}", e);
    };

    // 启动web服务
    thread::spawn(move || {
        let rt = Runtime::new().expect("Failed to create runtime");
        let _ = rt.block_on(async { webserver::web_server_setup().await });
    });

    Ok(())
}
